home *** CD-ROM | disk | FTP | other *** search
Text File | 1990-08-17 | 32.7 KB | 817 lines | [TEXT/CCL ] |
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;; pict-dialog-items.lisp
- ;;
- ;; Copyright 1990 by Ruben Kleiman for Apple Computer, Inc.
- ;; Advanced Technology Group
- ;;
- ;; This file defines pict-dialog-items which work like PICT buttons.
- ;; *pict-dialog-item* can be copy and pasted to/from the clipboard.
- ;; This permits you to directly import and export a PICT from
- ;; another MultiFinder application.
- ;;
- ;; Functionality:
- ;; A *pict-dialog-item* is associated with a PICT resource. The
- ;; PICT resource may be generated either by associating it with a PICT
- ;; resource or by pasting from the clipboard.
- ;;
- ;; See example at end of this file for the possible initial arguments
- ;; that can be passed to ONEOF for *pict-dialog-item*. The example
- ;; shows how you can create a *pict-dialog-item* in a dialog
- ;; and how you can associate it with a PICT resource from a resource file.
- ;;
- ;; LAST MODIFIED: 5/14/90
- ;;
-
- ;(require :resources) ; This is needed for CONVERT-HANDLE-TO-RESOURCE and DELETE-RESOURCE functions
-
-
- (EVAL-WHEN (EVAL COMPILE)
- (REQUIRE :TRAPS)
- (REQUIRE :RECORDS))
-
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;; *pict-dialog-item*
- ;;
- ;; the new class inherits from *dialog-item*
- ;;
- ;; Initialization arguments include:
- ;;
- ;; :my-pict-id
- ;; associates the dialog item with a PICT resource ID. The
- ;; PICT will be loaded as necessary. You should have opened
- ;; the resource file in which this resource exists.
- ;; DEFAULT: no association
- ;;
- ;; :zoom-factor
- ;; establishes a zoom factor for drawing the PICT. See
- ;; comments in the function DIALOG-ITEM-DRAW below.
- ;; DEFAULT: -1
- ;;
- ;; :purgeable
- ;; set to a non-nil value ensures that if the dialog item is
- ;; associated with a resource, then it will be purgeable.
- ;; Unpurgeable items improve performance in cases where memory is low;
- ;; but purgeable items stretch memory by pushing the PICT to disk
- ;; when it is not used AND memory is needed for something else.
- ;; DEFAULT: NIL
- ;;
- ;; :my-filename
- ;; set to the resource file name with which this dialog item's PICT
- ;; resource is associated.
- ;;
- ;; :locked
- ;; set to a non-nil value, it ensures that if the dialog item is
- ;; associated with a resource, then it will be locked.
- ;; This will improve performance, but should be used with great
- ;; care because it can lead to fragmented memory.
- ;; DEFAULT: NIL
- ;;
- (defobject *pict-dialog-item* *dialog-item*)
-
-
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;
- ;;exist
- ;;
- ;;an added init-list option :pict-ID allows the caller specify which pict to use.
- ;; the default is to use the :SCRAP pict
- ;;
-
- (defobfun (exist *pict-dialog-item*) (init-list)
- (let ((dialog (getf init-list :my-dialog nil))
- (purgeable-res (getf init-list :purgeable NIL))
- (locked-res (getf init-list :locked nil))
- (id (getf init-list :pict-id :SCRAP))
- (filename (getf init-list :my-filename nil)))
- (and filename (setq filename (expand-logical-namestring filename)))
- (have 'my-filename filename)
- (unless dialog
- (error "You must supply the dialog in :MY-DIALOG"))
- ;; REGULAR HANDLES MUST NOT BE PURGEABLE, ELSE PICT IS LOST!
- (setq purgeable-res (and (numberp id) purgeable-res))
- (have 'my-pict-id id) ; PICTURE RESOURCE ID OR WAITING FOR SCRAP
- (have 'my-pict-handle nil) ; HANDLE TO PICT RESOURCE OR JUST TO PICT IN MEMORY
- (have 'resource-p (numberp id)) ; IS MY-PICT-HANDLE A HANDLE TO A RESOURCE?
- (have 'zoom-factor nil) ; HOW TO SCALE THE PICT FOR DRAWING
- (have 'purgeable purgeable-res) ; SHOULD RESOURCE BE PURGEABLE?
- (have 'locked locked-res) ; SHOULD RESOURCE BE LOCKED?
- ;; TRY TO LOAD PICT FROM RESOURCE, IF NECESSARY
- (load-pict purgeable-res locked-res)
- (usual-exist init-list)
- (have 'my-dialog dialog) ; DIALOG TO WHICH PICT BELONGS (MUST BE SUPPLIED)
- (zoom-by-factor (getf init-list :zoom-factor -1)))) ; INITIALIZE SCALE FACTOR NOW!
-
-
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;
- ;;load-pict
- ;;
- ;; If there's a pict-id, it loads the PICT from the current resource map.
- ;; Else, if there's a filename, then it loads the first PICT resource it sees
- ;; in that file's resource map.
- ;; Else, this dialog item must be waiting to be pasted onto from the scrap
- ;; during a later (or ongoing) paste operation.
- ;;
- (defobfun (load-pict *pict-dialog-item*) (purgeable locked
- &aux (found-handle nil)
- (curresfile (_curresfile :errchk :word)))
- (declare (object-variable my-pict-id my-pict-handle resource-p))
- (unwind-protect
- (progn
- (when my-filename
- ;; OPEN PICT FROM RESOURCE FILE IF FILE ALREADY EXISTS:
- (when (probe-file my-filename)
- (unless (numberp my-pict-id)
- (map-resources "PICT"
- #'(lambda (handle)
- (setq found-handle handle))
- :resource-filename my-filename
- :close-file nil
- :make-current t)
- (if found-handle
- (multiple-value-bind (res-type res-id res-name res-size)
- (get-resource-info found-handle)
- (setq my-pict-id res-id))
- (error "Could not find a PICT inside file ~a" my-filename)))))
- ;; NOW GET THE PICTURE, IF NECESSARY:
- (cond ((eq my-pict-id :scrap))
- ((numberp my-pict-id)
- (when (null (setq my-pict-handle (_getpicture :word my-pict-id :ptr)))
- (error "PICT RESOURCE ID ~A NOT FOUND." my-pict-id))
- (unless purgeable
- (_hnopurge :errchk :A0 my-pict-handle :D0))
- (when locked
- (_hlock :errchk :A0 my-pict-handle)))
- ((error ":PICT-ID must either be a number or :SCRAP; was ~s" my-pict-id))))
- (_useresfile :errchk :word curresfile)
- (_reserror :errchk)))
-
-
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;
- ;;start-drawing
- ;;
- ;; Initiates drawing into this *pict-dialog-item*. Any quickdraw commands
- ;; drawn into the picture and terminated with a stop-drawing command
- ;; will be recorded into this *pict-dialog-item* for later replay or
- ;; simply to save it.
- ;; The optional DRAW-ON-SCREEN parameter allows you to actually see what
- ;; is being drawn into the *pict-dialog-item*, as long as it partially
- ;; shows on the window in which it is being drawn.
- ;;
- ;; Note: recording will be clipped by the size of this picture. For
- ;; your convenience, start-drawing optionally accepts a new size for the *pict-dialog-item*.
- ;;
- (defobfun (start-drawing *pict-dialog-item*) (&key left top right bottom
- (draw-on-screen nil)
- &aux (me (self))
- (dialog my-dialog))
- (unless my-filename (error "You should have associated a file with this drawing!"))
- (when my-pict-handle (error "You already have a drawing stored in this picture!"))
- (unless left
- (let ((size (ask dialog (rref wptr :window.portrect))))
- (setq left (rref size :rect.left)
- top (rref size :rect.top)
- right (rref size :rect.right)
- bottom (rref size :rect.bottom))))
- (if left
- (unless (and top right bottom)
- (error "Must supply ALL coordinates onto which to draw.")))
- (ask me (set-dialog-item-size (make-point (abs (- right left)) (abs (- bottom top)))))
- (ask dialog (start-picture left top right bottom))
- (if draw-on-screen
- (ask dialog (rset wptr :cgrafport.pnvis 0))))
-
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;
- ;;stop-drawing
- ;;
- ;; Stops drawing into this *pict-dialog-item*. (See start-drawing.)
- ;; Hereafter, this picture will display what you have recorded into it.
- ;; You should supply the pathname to the file in which you want this
- ;; resource saved. If you don't supply one, then the resource will
- ;; be saved into the currently open resource file.
- ;;
- (defobfun (stop-drawing *pict-dialog-item*) (&key (resource-name "")
- &aux (dialog (objvar my-dialog)))
- (unless my-filename (error "You should have associated a file with this drawing!"))
- (setq my-pict-handle (ask dialog (get-picture)))
- (multiple-value-bind (type ID)
- (convert-handle-to-resource my-pict-handle "PICT"
- :filename my-filename
- :resource-name resource-name)
- (setq my-pict-id ID
- resource-p T))
- (ask dialog (rset wptr :cgrafport.pnvis 0))) ; MAKE SURE THAT WE CAN NOW DRAW INTO SCREEN
-
-
-
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;
- ;;remove-self-from-dialog
- ;;
- ;; Makes sure that the PICT is cleaned up.
- ;;
- (defobfun (remove-self-from-dialog *pict-dialog-item*) ()
- (declare (object-variable my-pict-handle resource-p))
- (when (handlep my-pict-handle)
- (if resource-p
- (_releaseresource :ptr my-pict-handle :word)
- (_killpicture :errchk :ptr my-pict-handle))
- (setq my-pict-handle nil))
- ;;; CLOSE RESOURCE FILE, IF NECESSARY:
- (let ((n (with-pstrs ((fn (expand-logical-namestring my-filename)))
- (prog1 (_openresfile :errchk :ptr fn :word)
- (_reserror :errchk)))))
- (_closeresfile :errchk :word n)
- (_reserror :errchk))
- (usual-remove-self-from-dialog))
-
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;
- ;;dialog-item-draw
- ;;
- ;; zoom-factor DETERMINES HOW THE PICT IS ZOOMED:
- ;;
- ;; zoom-factor = 0
- ;; Draw PICT to fit visible window
- ;;;;; Draw PICT from PICT resource size information,
- ;;;;; starting at window origin
- ;; zoom-factor > 0
- ;; Draw PICT starting at dialog-item-position,
- ;; scale height and width from dialog-item-size
- ;; multiplied by zoom-factor
- ;; zoom-factor < 0
- ;; Draw PICT starting at dialog-item-position,
- ;; scale height and width from resource size
- ;; information multiplied by absolute value of zoom-factor
- ;;
- ;;
- (defobfun (dialog-item-draw *pict-dialog-item*) ()
- (declare (object-variable my-dialog my-pict-handle zoom-factor resource-p wptr purgeable
- CCL::dialog-item-position-iv CCL::dialog-item-size-iv))
- (when (handlep my-pict-handle)
- (let* ((dialog my-dialog)
- (pict-handle my-pict-handle)
- (topleft (dialog-item-position))
- (size (dialog-item-size))
- (bottomright (add-points topleft size))
- (dwptr (if (ask dialog (boundp 'wptr)) ; TO GET AROUND MACL VIEW BUG IN 1.3.1
- (ask dialog wptr))))
- (when dwptr
- ;; RELOAD RESOURCE IF NECESSARY
- (when (and resource-p
- purgeable
- (null (%get-ptr pict-handle)))
- (_loadresource :errchk :ptr pict-handle))
- ;; RECT ALLOCATED ON STACK, SO IT WON'T BUMP RESOURCE EVEN IF WE DON'T HAVE THE EXTRA WORD!
- (rlet ((r :rect :topleft topleft :bottomright bottomright))
- (with-port dwptr
- (_DrawPicture :ptr pict-handle :ptr r)))))))
-
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;
- ;;zoom-by-factor and zoom-factor
- ;;
- ;; Use this accessors to zoom and to get the current zoom factor.
- ;; The zoom allows you to respecify the upper-left hand corner
- ;; to position and/or the size of the *pict-dialog-item*.
- ;; You may optionally require the zoom to redraw the *pict-dialog-item*.
- ;; The semantics of the zoom factor number are explained in
- ;; the DIALOG-ITEM-DRAW object function for *pict-dialog-item*.
- ;;
-
- (defobfun (zoom-factor *pict-dialog-item*) ()
- (declare (object-variable zoom-factor))
- zoom-factor)
-
- (defobfun (zoom-by-factor *pict-dialog-item*) (factor &key redraw position size)
- (declare (object-variable zoom-factor CCL::dialog-item-position-iv CCL::dialog-item-size-iv))
- (unless (numberp factor)
- (error "Scale factor must be a number"))
- ;; (and (< factor 1) (> factor 0) (inval-dialog-item)) SHOULD BE DONE BY WINDOW
- (setq zoom-factor factor
- CCL::dialog-item-position-iv (or position (get-real-position))
- CCL::dialog-item-size-iv (or size (get-real-size)))
- (when redraw (dialog-item-draw)))
-
-
-
-
-
-
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;
- ;;get-real-size
- ;;
- ;; The size of the *pict-dialog-item* may be the usual dialog item size
- ;; or it may be based on the position and size information in the PICT
- ;; resource, depending on the value of zoom-factor. (See comments for
- ;; DIALOG-ITEM-DRAW to understand the motivation for this.)
- ;;
- (defobfun (get-real-size *pict-dialog-item*) (&aux pict-size
- (dialog my-dialog))
- (declare (object-variable zoom-factor my-pict-handle my-dialog
- resource-p purgeable))
- (if (zerop zoom-factor)
- ;; CALCULATE SIZE FROM WINDOW SIZE INFO:
- (setq pict-size (ask dialog (window-size)))
- (if (> zoom-factor 0)
- ;; CALCULATE SIZE FROM DIALOG ITEM SIZE INFO:
- (setq pict-size (dialog-item-size))
- ;; CALCULATE SIZE FROM PICT RESOURCE SIZE INFO:
- (let* ((pict-handle (progn
- (if (and resource-p
- purgeable
- (null (%get-ptr my-pict-handle)))
- (_loadresource :ptr my-pict-handle))
- my-pict-handle))
- (topleft (rref pict-handle picture.picframe.topleft))
- (bottomright (rref pict-handle picture.picframe.bottomright)))
- (setq pict-size (subtract-points bottomright topleft)))))
- (if (or (zerop zoom-factor)
- (= zoom-factor 1))
- pict-size ; SCALING IS UNNECESSARY
- (make-point (truncate (* (abs zoom-factor)
- (point-h pict-size)))
- (truncate (* (abs zoom-factor)
- (point-v pict-size))))))
-
-
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;
- ;;get-real-position
- ;;
- ;; The position of the *pict-dialog-item* may be the usual dialog item position
- ;; or it may be based on the position information in the PICT
- ;; resource, depending on the value of zoom-factor. (See comments for
- ;; DIALOG-ITEM-DRAW to understand the motivation for this.)
- ;;
- (defobfun (get-real-position *pict-dialog-item*) ()
- (declare (object-variable zoom-factor my-pict-handle resource-p purgeable))
- (if (zerop zoom-factor)
- ;; DIALOG ITEM STARTS AT TOPLEFT OF WINDOW
- #@(0 0)
- (if (> zoom-factor 0)
- ;; DIALOG ITEM STARTS AT USUAL DIALOG ITEM POSITION
- (dialog-item-position)
- ;; DIALOG ITEM STARTS AT PICT RESOURCE TOPLEFT POSITION
- (let ((pict-handle (progn
- (if (and resource-p
- purgeable
- (null (%get-ptr my-pict-handle)))
- (_loadresource :ptr my-pict-handle))
- my-pict-handle)))
- (rref pict-handle picture.picframe.topleft)))))
-
-
-
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;
- ;;dialog-item-click-event-handler
- ;;
- ;; this function is called whenever the user clicks in the dialog item. It
- ;; is called on mouse-down, not on mouse-up.
- ;;
- ;; the version defined below tracks the mouse, inverting the pict as long
- ;; as the mouse is over it. If the user releases the mouse-button while the
- ;; the mouse is over the pict, the pict's dialog-item-action is called.
- ;;
- ;;
- (defobfun (dialog-item-click-event-handler *pict-dialog-item*) (where)
- (declare (object-variable my-dialog zoom-factor wptr)
- (ignore where))
- (let* ((pos (dialog-item-position))
- (size (dialog-item-size))
- (mtop (point-v pos))
- (mleft (point-h pos))
- (mbottom (point-v (add-points pos size)))
- (mright (point-h (add-points pos size)))
- (inverted-p nil)
- (item (self)))
- (ask my-dialog
- (with-port wptr
- (rlet ((temp-rect :rect
- :top mtop
- :left mleft
- :bottom mbottom
- :right mright))
- (without-interrupts
- (_inverrect :ptr temp-rect)
- (setq inverted-p t)
- (loop
- (unless (mouse-down-p)
- (when inverted-p
- (ask item (dialog-item-action))
- (_inverrect :ptr temp-rect))
- (return-from dialog-item-click-event-handler))
- (if (logbitp 8 (_PtInRect
- :long (window-mouse-position)
- :ptr temp-rect
- :word))
- (unless inverted-p
- (_inverrect :ptr temp-rect)
- (setq inverted-p t))
- (when inverted-p
- (_inverrect :ptr temp-rect)
- (setq inverted-p nil))))))))))
-
-
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;
- ;;dialog-item-action
- ;;
- ;; when the user releases the mouse with the cursor over the pict,
- ;; dialog-item-click-event-handler leaves the pict highlighted and calls
- ;; dialog-item-action. For this reason, the usual-dialog-item-action
- ;; redraws the pict to un-invert it.
- ;;
- ;;;(defobfun (dialog-item-action *pict-dialog-item*) ()
- ;;; (usual-dialog-item-action))
-
-
-
-
-
-
-
-
-
-
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;
- ;;Scrap handling for *pict-dialog-item*
- ;;
- ;; MACL's convention for scrap handler requires them to be instances
- ;; of a class: ugly... but who's perfect?
- ;;
- (defvar *pict-scrap-handler* (oneof *scrap-handler*))
-
- (setq *scrap-handler-alist*
- (nconc *scrap-handler-alist*
- `((:PICT . ,*pict-scrap-handler*))))
-
-
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;
- ;;set-internal-scrap
- ;;
- ;; Puts a PICT into the MACL private scrap, disposing of old one
- ;; before overwriting it. Uses pict-handle instead of internal-scrap ivar
- ;; to avoid having a handle clobbered by Fred or text edit boxes.
- ;; PICTs are handles to memory resources: one cannot assume that the
- ;; garbage collector will take care of it!
- ;;
- (defobfun (set-internal-scrap *pict-scrap-handler*) (new-scrap)
- (declare (object-variable internal-scrap))
- (let ((pict-handle internal-scrap))
- (or (handlep new-scrap)
- (null new-scrap)
- (error "SCRAP ITEM ~S SHOULD BE A HANDLE OR NIL." new-scrap))
- (and (handlep pict-handle)
- (_killpicture :errchk :ptr pict-handle))
- (usual-set-internal-scrap new-scrap)
- (and new-scrap
- (pushnew :PICT *scrap-state*))))
-
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;
- ;;internalize-scrap
- ;;
- ;; Copies a PICT from the public scrap into the MACL private scrap.
- ;; When called, we already know that a PICT is waiting in the scrap.
- ;; Also, set-internal-scrap will have been called with a NIL argument,
- ;; forcing the old internal PICT to have been killed.
- ;;
- (defobfun (internalize-scrap *pict-scrap-handler*) (&aux pict-handle)
- (declare (object-variable internal-scrap))
- (setq pict-handle (_newhandle :errchk :D0 0 :A0))
- (_GetScrap :ptr pict-handle :ostype :PICT :long #xA78)
- (setq internal-scrap pict-handle))
-
-
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;
- ;;get-internal-scrap
- ;;
- ;; Gets the PICT resource from the private scrap.
- ;;
- (defobfun (get-internal-scrap *pict-scrap-handler*) ()
- (declare (object-variable internal-scrap))
- internal-scrap)
-
-
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;
- ;;externalize-scrap
- ;;
- ;; Gets a PICT from the internal scrap and copies it into the public scrap.
- ;; If memory is low, it tries its best in memory or does it on disk.
- ;;
- (defobfun (externalize-scrap *pict-scrap-handler*) ()
- (declare (object-variable internal-scrap))
- (labels ((put-pictscrap (size handle)
- (with-dereferenced-handles ((p handle))
- (_putscrap :long size :ostype :PICT :ptr p :long))))
- (let* ((pict-handle internal-scrap)
- (pict-size (if (handlep pict-handle)
- 251266 ; (rref pict-handle :picture.picsize) ;; was (- (_gethandlesize :a0 pict-handle :d0) 8)
- 0))
- (scrapptr (_infoscrap :long))
- old-scrapsize
- result)
- (when (> pict-size 0) ; A HANDLE WITH REAL CONTENTS TO EXTERNALIZE!
- (_zeroscrap :errchk)
- (cond ((rref scrapptr :scrapstuff.scraphandle) ; SCRAP IS IN MEMORY
- (setq old-scrapsize (rref scrapptr :scrapstuff.scrapsize)
- result (put-pictscrap pict-size pict-handle))
- (when (\= result 0) ; FAILED: RESTORE OLD SCRAP AND TRY TO FIND MEMORY
- (rset scrapptr :scrapstuff.scrapsize old-scrapsize)
- (_sethandlesize :errchk
- :A0 (rref scrapptr :scrapstuff.scraphandle)
- :D0 old-scrapsize)
- (if (> (_maxmem :errchk :D0) pict-size)
- (setq result (put-pictscrap pict-size pict-handle)))
- (when (\= result 0) ; FAILED AGAIN: RESTORE OLD SCRAP AND DO ON DISK
- (rset scrapptr :scrapstuff.scrapsize old-scrapsize)
- (_sethandlesize :errchk
- :A0 (rref scrapptr :scrapstuff.scraphandle)
- :D0 old-scrapsize)
- (_unlodescrap :errchk) ; UNLOAD SCRAP TO DISK
- (put-pictscrap pict-size pict-handle))))
- (t ; SCRAP IS ON DISK
- (put-pictscrap pict-size pict-handle)))))))
-
-
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;
- ;;paste for *dialog* redefined!!!
- ;;
- ;; Wherein *dialog* is taught to handle *pict-dialog-item*s.
- ;; To be really general, there should be a cut, copy, and paste dispatcher
- ;; for each scrap type which does the right thing: but doing this would require
- ;; patching too much of the underlying MACL code. So...
- ;;
- ;; This overrides MACL's PASTE method for the *dialog* class.
- ;;
- (defobfun (paste *dialog*) ()
- (if (memq :PICT *scrap-state*)
- ; PASTING A PICT CREATES A *pict-dialog-item* INSTANCE IN THE DIALOG
- (let* ((me (self))
- (pict-di (oneof *pict-dialog-item* :my-dialog me)))
- (add-dialog-items pict-di)
- (ask pict-di (paste)))
- (let ((cur (current-editable-text)))
- (when cur (ask cur (paste))))))
-
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;
- ;;copy for *dialog* NOT redefined!!!
- ;;
- ;; Again, MACL doesn't have a general way of dealing with a selected dialog item.
- ;; So, instead of mucking too much with the architecture and making future compatibility
- ;; more difficult, we leave it alone for YOU to muck with!
- ;;
- ;(defobfun (copy *dialog*) ()
- ; (let* ((cur (current-editable-text)))
- ; (when cur (ask cur (copy)))))
-
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;
- ;;cut for *dialog* NOT redefined!!!
- ;;
- ;; Again, MACL doesn't have a general way of dealing with a selected dialog item.
- ;; So, instead of mucking too much with the architecture and making future compatibility
- ;; more difficult, we leave it alone for YOU to muck with!
- ;;
- ;;;(defobfun (cut *dialog*) ()
- ;;; (let* ((cur (current-editable-text)))
- ;;; (when cur (ask cur (cut)))))
-
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;
- ;;clear for *dialog* NOT redefined!!!
- ;;
- ;; Again, MACL doesn't have a general way of dealing with a selected dialog item.
- ;; So, instead of mucking too much with the architecture and making future compatibility
- ;; more difficult, we leave it alone for YOU to muck with!
- ;;
- ;;;(defobfun (clear *dialog*) ()
- ;;; (let* ((cur (current-editable-text)))
- ;;; (when cur (ask cur (clear)))))
-
-
-
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;
- ;;paste for *pict-dialog-item*
- ;;
- ;; Wherein *pict-dialog-item* paints itself from the scrap!
- ;; This is dispatched by the *dialog*'s PASTE method.
- ;;
- (defobfun (paste *pict-dialog-item*) ()
- (declare (object-variable my-pict-handle my-pict-id))
- (when (handlep my-pict-handle)
- (error "CAN'T PASTE INTO DIALOG ITEM ~a" (self))) ; IN CASE IT'S ATTEMPTED!
- (let ((pict (ask *pict-scrap-handler* (get-internal-scrap))))
- (when (handlep pict)
- (without-interrupts
- (_hlock :errchk :A0 pict)
- (setq my-pict-handle (_handtohand :errchk :A0 pict :A0)) ; GET A COPY
- (_hnopurge :A0 my-pict-handle)
- (setq my-pict-id nil)
- ;; SCALE PICT TO ITS NATIVE SIZE STARTING AT HOME
- (zoom-by-factor -1 :position #@(0 0))
- (_hunlock :errchk :A0 pict))
- (dialog-item-draw)))) ; NOW DRAW SELF
-
-
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;
- ;;copy for *pict-dialog-item*
- ;;
- ;; Wherein *pict-dialog-item* copies itself to the scrap!
- ;;
- (defobfun (copy *pict-dialog-item*) ()
- (declare (object-variable my-pict-handle))
- (let ((pict-handle my-pict-handle))
- (unless (handlep pict-handle)
- (error "PICT DIALOG ITEM ~a DOES NOT CONTAIN A PICTURE." (self)))
- (let (new-pict)
- (_hlock :errchk :A0 pict-handle)
- (setq new-pict (_handtohand :errchk :A0 pict-handle :A0))
- (_hnopurge :A0 new-pict :D0)
- (_hunlock :errchk :A0 pict-handle)
- (put-scrap :PICT new-pict t)))) ; MAY NOT BE NECESSARY TO OVERWRITE...
-
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;
- ;;clear for *pict-dialog-item*
- ;;
- ;; Wherein *pict-dialog-item* clears itself
- ;;
-
-
- (provide ':pict-dialog-items)
- (pushnew ':pict-dialog-items *features*)
-
-
- #| SAMPLES:
-
- (defobject *our-color-dialog* *color-dialog*) ; MAKING IT CONVENIENT TO DISSECT WINDOW BY SUBCLASSING
-
- ;;; TWO SAMPLES FOLLOW:
- ;;; 1. WE OPEN A RESOURCE FILE WITH PICT RESOURCES IN IT. THEN, WE CREATE A
- ;;; WINDOW & A *pict-dialog-item* INTO WHICH WE WILL PUT A PICT RESOURCE
- ;;; FROM THE OPENED FILE. THEN WE PLAY AROUND WITH IT. WE FINALLY CUT
- ;;; AND PASTE IT INTO ANOTHER PROGRAM.
- ;;;
- ;;; 2. WE CREATE A WINDOW & A *pict-dialog-item* WITHOUT ANY PICT RESOURCE
- ;;; ASSOCIATED WITH IT. WE START RECORDING DRAWING CALLS INTO IT.
- ;;; WE PLAY WITH IT AFTER WE STOP RECORDING. THEN WE CLOSE THE WINDOW
- ;;; AND RELOAD THE RECORDED PICTURE FROM A FILE INTO WHICH WE SAVED IT.
- ;;;
-
- ;;; 1. PLAYING WITH A PICTURE FROM AN EXISTING PICTURE RESOURCE FILE:
-
- (open-resource-file "macframes;frameset-kernel:allegro:navigator:PICT")
-
- (let ((a-dialog (oneof *our-color-dialog*
- :window-size #@(400 400)
- :window-title "PICTs"
- :window-position #@(40 40)
- :window-type :document-with-zoom)
- ))
- (ask a-dialog
- (add-dialog-items
- (oneof *pict-dialog-item*
- :my-dialog a-dialog
- :pict-id 69
- :purgeable T
- :zoom-factor 0
- :dialog-item-position #@(10 10)
- :dialog-item-size #@(200 200)
- :dialog-item-action '(progn
- (format t "YOU ARE LOOKING AT PICT ID ~a." (objvar my-pict-id))
- (ed-beep)
- (usual-dialog-item-action))))))
-
- ;;; GET THE WINDOW AND *PICT-DIALOG-ITEM*:
- (setq w (car (windows *our-color-dialog*)))
- (setq d (car (ask w (dialog-items))))
- ;;; CHECK IT OUT:
- (ask d (zoom-factor))
- (point-string (ask d (get-real-size)))
- (point-string (ask d (get-real-position)))
- (point-string (ask d (dialog-item-position)))
- (point-string (ask d (dialog-item-size)))
- ;;; PLAY WITH IT:
- (ask d (zoom-by-factor 0 :redraw t))
- (ask d (dialog-item-draw))
- (ask d (set-dialog-item-size #@(100 100)))
- (ask D (set-dialog-item-position #@(100 200)))
- (ask D (set-dialog-item-size #@(50 50)))
- ;;; COPY IT INTO THE CLIPBOARD:
- (ask d (copy))
- ;;; NOW GO TO A PAINT PROGRAM (e.g., Studio 8) IN MULTIFINDER AND DO A PASTE.
- ;;; THE PICTURE YOU JUST COPIED FROM ALLEGRO SHOULD HAVE BEEN
- ;;; PASTED INTO THE WINDOW IN YOUR PAINT PROGRAM.
-
-
-
-
-
-
- ;;; TESTING DRAWING INTO A *PICT-DIALOG-ITEM* AND SAVING IT IN A RESOURCE FILE.
-
- ;;; THIS CREATES A DIALOG WINDOW WHICH WE'LL USE:
- (setq our-dialog (oneof *our-color-dialog*
- :window-title "Recording A Drawing Demo"
- :window-size (make-point (- *screen-width* 40) (- *screen-height* 40))
- :window-position (make-point 40 40)))
-
- ;;; THIS CREATES A PICTURE DIALOG ITEM WHICH WE'LL INSERT INTO THE WINDOW:
- (setq our-drawing (oneof *pict-dialog-item*
- :my-filename "ccl;Demo-File-With-Drawing"
- :my-dialog our-dialog
- :pict-id :scrap
- :zoom-factor 0
- :dialog-item-position #@(0 0)
- :dialog-item-size (ask our-dialog (window-size))
- :dialog-item-action
- '(progn
- (ed-beep)
- (format t "~%You are at (~a,~a)."
- (point-h (ask (objvar my-dialog) (window-mouse-position)))
- (point-v (ask (objvar my-dialog) (window-mouse-position)))))))
-
- ;;; WE INSERT OUR DIALOG ITEM INTO OUR WINDOW:
- (ask our-dialog (add-dialog-items our-drawing))
-
- ;;; WE COMMAND IT TO START RECORDING OUR SUBSEQUENT DRAWING COMMANDS.
- ;;; WE TELL IT THAT WE WANT TO SEE WHAT WE ARE DRAWING:
- (ask our-drawing (start-drawing :draw-on-screen T))
-
- ;;; LET'S DRAW SOMETHING INTO THE DIALOG WINDOW: [THIS IS BEING RECORDED AS WE DRAW IT]
- (ask our-dialog (frame-rect 100 100 200 200))
- (ask our-dialog (frame-rect 110 110 190 190))
- (ask our-dialog (frame-rect 120 120 180 180))
- (ask our-dialog (frame-rect 130 130 170 170))
- (ask our-dialog (paint-rect 140 140 160 160))
-
- ;;; STOP RECORDING WHAT WE'RE DRAWING:
- (ask our-drawing (stop-drawing :resource-name "My Drawing"))
-
- ;;; CHECK WHETHER DRAWING WAS ACTUALLY SAVED TO A FILE (ELSE, THERE WAS SOME PROBLEM):
- (let ((filename (ask our-drawing my-filename)))
- (if (probe-file filename)
- (format t "~%Great! The drawing is saved in file ~s" filename)
- (error "The drawing file ~s somehow was not created!" filename)))
-
- ;;; LET'S PLAY WITH OUR DRAWING IN OUR WINDOW:
- (ask our-drawing (set-dialog-item-size (make-point 200 200))) ; CHANGE ITS SIZE
- (ask our-drawing (zoom-by-factor 0 :redraw T)) ; MAKE IT ZOOM TO FIT OUR WINDOW
- (ask our-drawing (zoom-by-factor 1.5 :redraw T)) ; MAKE IT ZOOM TO BE BIGGER BY 1/2 THAN OUR WINDOW
- (ask our-drawing (set-dialog-item-position (make-point -100 -100))) ; MOVE IT
- (ask our-drawing (set-dialog-item-position (make-point -100 100))) ; MOVE IT
-
- ;;; LET'S NOW GET RID OF OUR WINDOW:
- (ask our-dialog (window-close))
-
- ;;; LET'S OPEN OUR DRAWING INTO A NEW WINDOW:
- (setq our-dialog (oneof *our-color-dialog*
- :window-title "Drawing A Recorded Drawing Demo"
- :window-size (make-point (- *screen-width* 40) (- *screen-height* 40))
- :window-position (make-point 40 40)))
-
- ;;; THIS CREATES A PICTURE DIALOG ITEM WHICH WE'LL INSERT INTO THE WINDOW:
- (setq our-drawing (oneof *pict-dialog-item*
- :my-filename "ccl;Demo-File-With-Drawing"
- :my-dialog our-dialog
- :pict-id :scrap
- :zoom-factor 0
- ; :dialog-item-position #@(0 0)
- ; :dialog-item-size (ask our-dialog (window-size))
- :dialog-item-action
- '(progn
- (ed-beep)
- (format t "~%You are at (~a,~a)."
- (point-h (ask (objvar my-dialog) (window-mouse-position)))
- (point-v (ask (objvar my-dialog) (window-mouse-position)))))))
-
-
- ;;; WE INSERT OUR DIALOG ITEM INTO OUR WINDOW:
- (ask our-dialog (add-dialog-items our-drawing))
-
- ;;; THE DRAWING SHOULD BE DISPLAYING IN OUR WINDOW.
-
- ;;; DELETE YOUR DRAWING FILE, IF YOU WANT:
- (ask our-dialog (window-close)) ; THIS WILL CLOSE OUR WINDOW & YOUR DRAWING FILE
- (delete-file "ccl;Demo-File-With-Drawing") ; THIS WILL DELETE IT
-
- |#
-
-
-